﻿using System;
using System.IO;
using System.Text;
using Com.PhilChuang.Pmvp.Model.Services;
using Com.PhilChuang.Pmvp.Ui.Views;
using Com.PhilChuang.Utils;

namespace Com.PhilChuang.Pmvp.Ui.Presenters
{
	public class AboutPresenter : AbstractGenericPresenter<IAboutView>
	{
		#region Instance Variables (EMPTY)
		#endregion

		#region Properties
		public AboutPresenterConfig Config
		{ get; set; }
		#endregion

		#region Constructors / Init / Dispose
		public AboutPresenter () : this (AppServiceLocator.Instance.GetImpl<AboutPresenterConfig> (), AppServiceLocator.Instance.GetImpl<IAboutView> ())
		{
		}

		public AboutPresenter (IAboutView view) : this (AppServiceLocator.Instance.GetImpl<AboutPresenterConfig> (), view)
		{
		}

		public AboutPresenter (AboutPresenterConfig config, IAboutView view) : base (view)
		{
			config.ThrowIfNull ("config");
			Config = config;
		}
		#endregion

		#region AbstractPresenter implementation
		/// <summary>
		/// Subscribe to View events after the View is registered during Presenter instantiation.
		/// Call base impl as the first step.
		/// </summary>
		protected override void SubscribeToViewEvents ()
		{
			base.SubscribeToViewEvents ();

			// IAboutView
			View.DoLaunchAppRateLink += OnDoLaunchAppRateLink;
			View.DoOpenSendFeedbackView += OnDoOpenSendFeedbackView;
			View.DoLaunchAppWebsiteLink += OnDoLaunchAppWebsiteLink;
			//View.DoLaunchDonateLink += OnDoLaunchDonateLink;
		}

		/// <summary>
		/// Unsubscribes to View events after the View has Closed.
		/// Call base impl as the first step.
		/// </summary>
		protected override void UnsubscribeFromViewEvents ()
		{
			base.UnsubscribeFromViewEvents ();

			// IAboutView
			View.DoLaunchAppRateLink -= OnDoLaunchAppRateLink;
			View.DoOpenSendFeedbackView -= OnDoOpenSendFeedbackView;
			View.DoLaunchAppWebsiteLink -= OnDoLaunchAppWebsiteLink;
			//View.DoLaunchDonateLink -= OnDoLaunchDonateLink;
		}

		/// <summary>
		/// Updates the View with Presenter data.
		/// Call base impl as the last step.
		/// </summary>
		protected override void UpdateToView ()
		{
			View.VersionInfo = Config.VersionInfo;
			//View.ShowDonateLink = !Config.DonateLink.IsNullOrEmptyOrBlank ();
			View.HelpContent = Config.HelpContentResourceStreamName != null ? GetResourceStreamString (Config.HelpContentResourceStreamName) : String.Empty;
			base.UpdateToView ();
		}
		#endregion

		#region IAboutView Events
		private void OnDoLaunchAppRateLink ()
		{
			View.EnableAllControls (false);
			ExecuteAsync (() => AppServiceLocator.Instance.GetImpl<ILaunchMarketplaceAppDetailsService> ().Launch ());
		}

		private void OnDoOpenSendFeedbackView ()
		{
			View.EnableAllControls (false);
			ExecuteAsync (() => new SendFeedbackPresenter ().Show ());
		}

		private void OnDoLaunchAppWebsiteLink ()
		{
			View.EnableAllControls (false);
			ExecuteAsync (() => AppServiceLocator.Instance.GetImpl<ILaunchLinkService> ().LaunchLink (Config.AppWebsiteLink));
		}

		//private void OnDoLaunchDonateLink ()
		//{
		//    AppIoC.Instance.GetImpl<ILaunchLinkService> ().LaunchLink (Config.DonateLink);
		//}
		#endregion

		#region Utility methods
		// TODO move these elsewhere?
		private Stream GetResourceStream (String resourceStreamName)
		{
			Stream str;
			try
			{
				str = Config.ResourceAssembly.GetManifestResourceStream (resourceStreamName);
			}
			catch (Exception e)
			{
				str = new MemoryStream (Encoding.UTF8.GetBytes (e.ToString ()));
			}
			return str;
		}

		private String GetResourceStreamString (String resourceStreamName)
		{
			try
			{
				using (var s = GetResourceStream (resourceStreamName))
				using (var sr = new StreamReader (s))
				{
					return sr.ReadToEnd ();
				}
			}
			catch (Exception e)
			{
				return e.ToString ();
			}
		}
		#endregion
	}
}